package com.ts.api.module.api.service.impl;


import com.gitee.apanlh.spring.BeanContextUtils;
import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.date.DateUtils;
import com.gitee.apanlh.util.reflection.ClassConvertUtils;
import com.gitee.apanlh.util.valid.ValidParam;
import com.ts.api.common.constant.common.CommonConstant;
import com.ts.api.common.constant.common.SwitchEnum;
import com.ts.api.common.redis.DataExchangeRedisKey;
import com.ts.api.module.api.entity.ApiUserRequest;
import com.ts.api.module.api.entity.bo.ApiParameterBO;
import com.ts.api.module.api.service.ApiBizApplyService;
import com.ts.api.module.api.service.ApiBizMultiPushService;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistributeResult;
import com.ts.api.module.product.entity.po.ProductApplyFlowPO;
import com.ts.api.module.product.entity.po.ProductPlanPO;
import com.ts.cache.apikey.ApiKeyCacheService;
import com.ts.cache.apikey.entity.ApiKeyCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class ApiBizMultiPushServiceImpl implements ApiBizMultiPushService {

    @Autowired
    private ApiBizApplyService apiBizApplyService;
    @Autowired
    private ApiKeyCacheService apiKeyCacheService;

    @Override
    public void multiDataExchange(ApiUserRequest apiUserRequest, PlanDistributeResult finalMatchPlan, List<PlanDistributeResult> listSucMatchResult) {
        //  业务参数
        String apiClientId = apiUserRequest.getApiClientId();
        String phoneMd5 = apiUserRequest.getPhoneMd5();

        //  只有API渠道才会有apiClientId
        if (ValidParam.isEmpty(apiClientId)) {
            return ;
        }

        //  API渠道多推
        if (ValidParam.isEmpty(listSucMatchResult)) {
            return ;
        }

        //  是否有开启多推的计划
        List<ProductPlanPO> listSucPlan = CollUtils.toList(listSucMatchResult, t -> t.getProductPlanPO());
        List<ProductPlanPO> listEnableMultiPlan = CollUtils.find(listSucPlan, t -> SwitchEnum.hasEnable(t.getEnableMultiPush()));
        if (ValidParam.isEmpty(listEnableMultiPlan) || listEnableMultiPlan.size() < 1) {
            return ;
        }

        //  记录多推流程
        String multiPushKey = apiClientId + ":" + phoneMd5;
        Thread.ofVirtual().start(() -> {
            Iterator<ProductPlanPO> iterator = listEnableMultiPlan.iterator();
            while (iterator.hasNext()) {
                ProductPlanPO multiPlan = iterator.next();
                Long multiPlanId = multiPlan.getId();

                //  过滤已经最优匹配过的机构
                if (Eq.object(finalMatchPlan.getProductPlanPO().getId(), multiPlanId)) {
                    continue;
                }

                PlanDistributeResult multiResultFlow = CollUtils.findOne(listSucMatchResult, t -> Eq.object(t.getProductPlanPO().getId(), multiPlanId));
                ProductApplyFlowPO multiPlanFlowPO = multiResultFlow.getCurrentDistributeFlow();
                DataExchangeRedisKey.MULTI_PUSH.rightPush(multiPushKey, multiPlanFlowPO);
            }
            DataExchangeRedisKey.MULTI_PUSH.expire(multiPushKey, DateUtils.getTomorrowMidnightMillis(), TimeUnit.MILLISECONDS);
        });
    }

    @Override
    public void multiApply(ApiUserRequest apiUserRequest, ApiParameterBO apiParameterBO, ProductApplyFlowPO productApplyFlowPO) {
        String phoneMd5 = apiUserRequest.getPhoneMd5();

        //  获取多推渠道主体及计划
        String key = apiUserRequest.getApiClientId() + ":" + phoneMd5;
        RedisTemplate<String, Object> redisTemplate = ClassConvertUtils.cast(BeanContextUtils.getBean("redisTemplate"));

        //  临时使用redis原生
        List<Object> range = redisTemplate.opsForList().range("multi_push_data_exchange:" + key, 0, -1);
        if (ValidParam.isEmpty(range)) {
            return ;
        }

        //  方便后续标记为本地存在，变成唤醒标记
        apiParameterBO.setHasLocalExist(true);
        //  设置多推模式
        apiParameterBO.setHasMultiPush(true);

        try {
            //  获取多推渠道标识
            List<ProductApplyFlowPO> multiFlowPO = ClassConvertUtils.cast(range);
            ApiKeyCache apiKeyCache = apiKeyCacheService.get(CommonConstant.MULTI_PUSH_CLIENT_ID);
            String multiApiClientId = apiKeyCache.getApiClientId();
            Long multiLoanChannelId = apiKeyCache.getLoanChannelId();

            for (int i = 0; i < multiFlowPO.size(); i++) {
                //  改变流程渠道，变为多推渠道标识
                ProductApplyFlowPO multiProductApplyFlowPO = multiFlowPO.get(i);
                multiProductApplyFlowPO.setApiClientId(multiApiClientId);
                multiProductApplyFlowPO.setLoanChannelId(multiLoanChannelId);

                Thread.ofVirtual().start(() -> {
                    try {
                        apiBizApplyService.apply(apiUserRequest, apiParameterBO, multiProductApplyFlowPO);
                    } catch (Exception e) {
                        // do noting
                    }
                });
            }
        } finally {
            DataExchangeRedisKey.MULTI_PUSH.delKey(key);
        }
    }
}
